package com.hlkj.baidu_push;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Map;

public class BaiduPush {
	public String mHttpMethod;
	public String mSecretKey;
	public static final String mUrl = "http://channel.api.duapp.com/rest/2.0/channel/";
	public static final String HTTP_METHOD_POST = "POST";
	public static final String HTTP_METHOD_GET = "GET";

	public BaiduPush(String http_mehtod, String secret_key, String api_key) {
		this.mHttpMethod = http_mehtod;
		this.mSecretKey = secret_key;
		RestApi.mApiKey = api_key;
	}

	private String urlencode(String str) throws UnsupportedEncodingException {
		String rc = URLEncoder.encode(str, "utf-8");
		return rc.replace("*", "%2A");
	}

	public String jsonencode(String str) {
		String rc = str.replace("\\", "\\\\");
		rc = rc.replace("\"", "\\\"");
		rc = rc.replace("'", "\\'");
		return rc;
	}

	@SuppressWarnings("unchecked")
	public String PostHttpRequest(RestApi data) {
		StringBuilder sb = new StringBuilder();

		String channel = (String) data.remove("channel_id");
		if (channel == null)
			channel = "channel";
		try {
			data.put("timestamp", Long
					.toString(System.currentTimeMillis() / 1000L));
			data.remove("sign");

			sb.append(this.mHttpMethod);
			sb.append("http://channel.api.duapp.com/rest/2.0/channel/");
			sb.append(channel);
			for (Map.Entry i : data.entrySet()) {
				sb.append((String) i.getKey());
				sb.append('=');
				sb.append((String) i.getValue());
			}
			sb.append(this.mSecretKey);

			System.out.println("PRE: " + sb.toString());
			System.out.println("UEC: "
					+ URLEncoder.encode(sb.toString(), "utf-8"));

			MessageDigest md = MessageDigest.getInstance("MD5");
			md.reset();

			md.update(urlencode(sb.toString()).getBytes());
			byte[] md5 = md.digest();

			sb.setLength(0);
			for (byte b : md5)
				sb.append(String.format("%02x", new Object[] { Integer
						.valueOf(b & 0xFF) }));
			data.put("sign", sb.toString());

			sb.setLength(0);
			for (Map.Entry i : data.entrySet()) {
				sb.append((String) i.getKey());
				sb.append('=');

				sb.append(urlencode((String) i.getValue()));
				sb.append('&');
			}
			sb.setLength(sb.length() - 1);
		} catch (Exception e) {
			e.printStackTrace();
		}

		StringBuilder response = new StringBuilder();
		HttpRequest("http://channel.api.duapp.com/rest/2.0/channel/" + channel,
				sb.toString(), response);
		System.out
				.println("URL==http://channel.api.duapp.com/rest/2.0/channel/"
						+ channel + sb);
		return response.toString();
	}

	private int HttpRequest(String url, String query, StringBuilder out) {
		HttpURLConnection connection = null;
		try {
			URL urlobj = new URL(url);
			connection = (HttpURLConnection) urlobj.openConnection();
			connection.setRequestMethod("POST");

			connection.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			connection
					.setRequestProperty("Content-Length", query.length() + "");
			connection.setRequestProperty("charset", "utf-8");

			connection.setUseCaches(false);
			connection.setDoInput(true);
			connection.setDoOutput(true);

			connection.setConnectTimeout(5000);
			connection.setReadTimeout(5000);
			
			// 数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后，应用程序可以使用数据输入流将数据读入。
			DataOutputStream wr = new DataOutputStream(connection
					.getOutputStream());
			wr.writeBytes(query.toString());
			wr.flush();
			wr.close();

			InputStream is = connection.getInputStream();
			//从字符输入流中读取文本，缓冲各个字符，从而实现字符、数组和行的高效读取。
			BufferedReader rd = new BufferedReader(new InputStreamReader(is));
			String line = null;
			while ((line = rd.readLine()) != null) {
				out.append(line);
				out.append('\r');
			}
			rd.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (connection != null) {
			connection.disconnect();
		}
		return 0;
	}

	public String QueryBindlist(String userid, String channelid) {
		RestApi ra = new RestApi("query_bindlist");
		ra.put("user_id", userid);
		ra.put("device_type", "3");
		ra.put("channel_id", channelid);
		ra.put("start", "0");
		ra.put("limit", "10");
		return PostHttpRequest(ra);
	}

	public String VerifyBind(String userid, String channelid) {
		RestApi ra = new RestApi("verify_bind");
		ra.put("user_id", userid);
		ra.put("device_type", "3");
		ra.put("channel_id", channelid);
		return PostHttpRequest(ra);
	}

	public String SetTag(String tag, String userid) {
		RestApi ra = new RestApi("set_tag");
		ra.put("user_id", userid);
		ra.put("tag", tag);
		return PostHttpRequest(ra);
	}

	public String FetchTag() {
		RestApi ra = new RestApi("fetch_tag");
		ra.put("name", "0");
		ra.put("start", "0");
		ra.put("limit", "10");
		return PostHttpRequest(ra);
	}

	public String DeleteTag(String tag, String userid) {
		RestApi ra = new RestApi("delete_tag");
		ra.put("user_id", userid);
		ra.put("tag", tag);
		return PostHttpRequest(ra);
	}

	public String QueryUserTag(String userid) {
		RestApi ra = new RestApi("query_user_tags");
		ra.put("user_id", userid);
		return PostHttpRequest(ra);
	}

	public String QueryDeviceType(String channelid) {
		RestApi ra = new RestApi("query_device_type");
		ra.put("channel_id", channelid);
		return PostHttpRequest(ra);
	}

	public String PushMessage(String message, String userid) {
		RestApi ra = new RestApi("push_msg");
		ra.put("message_type", "0");// 0：消息（透传给应用的消息体）1：通知（对应设备上的消息通知）
		ra.put("messages", message);
		ra.put("msg_keys", "msgkey");// 指定消息标识，必须和messages一一对应。相同消息标识的消息会自动覆盖
		ra.put("message_expires", "86400");// 指定消息的过期时间，默认为86400秒。
		ra.put("channel_id", "");
		ra.put("push_type", "1");// 1：单个人，必须指定user_id 和
		// channel_id（指定用户的指定设备）或者user_id（指定用户的所有设备）2：一群人，必须指定
		// tag 3：所有人，无需指定tag、user_id、channel_id

		ra.put("device_type", "3");// 1：浏览器设备；2：PC设备；3：Andriod设备；
		// 4：iOS设备；5：Windows Phone设备；

		ra.put("user_id", userid);// 用户标识，在Android里，channel_id +
		// userid指定某一个特定client。不超过256字节，如果存在此字段，则只推送给此用户。
		return PostHttpRequest(ra);
	}

	public String PushTagMessage(String message, String tag) {
		RestApi ra = new RestApi("push_msg");
		ra.put("message_type", "0");
		ra.put("messages", message);
		ra.put("msg_keys", "msgkey");
		ra.put("message_expires", "86400");
		ra.put("push_type", "2");
		ra.put("device_type", "3");
		ra.put("tag", tag);
		return PostHttpRequest(ra);
	}

	public String PushMessage(String message) {
		RestApi ra = new RestApi("push_msg");
		ra.put("message_type", "0");
		ra.put("messages", message);
		ra.put("msg_keys", "msgkey");
		ra.put("message_expires", "86400");
		ra.put("push_type", "3");
		ra.put("device_type", "3");
		return PostHttpRequest(ra);
	}

	public String PushMess(String message) {
		RestApi ra = new RestApi("push_msg");
		ra.put("message_type", "0");
		ra.put("messages", message);
		ra.put("msg_keys", "msgkey");
		ra.put("message_expires", "86400");
		ra.put("push_type", "3");
		ra.put("device_type", "3");
		return PostHttpRequest(ra);
	}

	public String PushNotifyMessage(String title, String messageOrContent,
			String userid, boolean allPeople) {
		RestApi ra = new RestApi("push_msg");
		ra.put("message_type", "1");

		String msg = String
				.format(
						"{'title':'%s','description':'%s','notification_builder_id':0,'notification_basic_style':7,'open_type':2,'custom_content':{'test':'test'}}",
						new Object[] { title, jsonencode(messageOrContent) });

		System.out.println(msg);

		ra.put("messages", msg);

		ra.put("msg_keys", "msgkey");
		if (allPeople)
			ra.put("push_type", "3");// 3推送给所有人
		else {
			ra.put("push_type", "1");
			ra.put("user_id", userid);
		}
		return PostHttpRequest(ra);
	}

	public String PushNotifySimple(String title, String messageOrContent,
			String userid, boolean allPeople) {
		RestApi ra = new RestApi("push_msg");
		ra.put("message_type", "1");

		String msg = String
				.format(
						"{'title':'%s','description':'%s','notification_builder_id':0,'notification_basic_style':7,'open_type':2,'custom_content':{'test':'test'}}",
						new Object[] { title, jsonencode(messageOrContent) });

		System.out.println(msg);

		ra.put("messages", msg);

		ra.put("msg_keys", "msgkey");
		if (allPeople)
			ra.put("push_type", "3");// 3推送给所有人
		else {
			ra.put("push_type", "1");
			ra.put("user_id", userid);
		}

		return PostHttpRequest(ra);
	}

	public String FetchMessage(String userid) {
		RestApi ra = new RestApi("fetch_msg");
		ra.put("user_id", userid);

		return PostHttpRequest(ra);
	}

	public String FetchMessageCount(String userid) {
		RestApi ra = new RestApi("fetch_msgcount");
		ra.put("user_id", userid);
		return PostHttpRequest(ra);
	}

	public String DeleteMessage(String userid, String msgids) {
		RestApi ra = new RestApi("delete_msg");
		ra.put("user_id", userid);
		ra.put("msg_ids", msgids);
		return PostHttpRequest(ra);
	}
}